package com.service;

import com.arcsoft.face.*;
import com.arcsoft.face.enums.*;
import com.arcsoft.face.toolkit.ImageFactory;
import com.arcsoft.face.toolkit.ImageInfo;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.arcsoft.face.toolkit.ImageInfoEx;

import static com.arcsoft.face.toolkit.ImageFactory.getGrayData;
import static com.arcsoft.face.toolkit.ImageFactory.getRGBData;

import com.util.FileDownloader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

@Service
public class FaceService {

    private static Logger logger = LoggerFactory.getLogger(FaceService.class);

    private FaceEngine faceEngine;

    private Map<String, FaceFeature> customerIdFeatureMap = new HashMap<>();

    public FaceService() throws Exception{
        try {

            //从官网获取
            String appId = "gNM8EUAw8KnCB4HTveHSQPzjrGKabrbkEv1Hb5U3FYn";
            String sdkKey = "B7XZB3xGW6uuTEqcF8gFsXjca5KhD7P2GLtdfmLZKu5k";
            //澳门236
            String activeKey = "/data/localfacerec/082Y113AR41CWN3A.dat";
            //binguo2222
//            String activeKey = "/data/localfacerec/082Y113AR425RL72.dat";
            //澳门114
//            String activeKey = "/data/face/082Y113AR43Z7M7D.dat";
            //兰溪
//            String activeKey = "/data/face/82Y11138V13BUTFQ.dat";
            //民生
//            String activeKey = "/data/localfacerec/82Y11138V11HEKJB.dat";
    //        String activeKey3 = "/data/localfacerec/82Y11138V126UQCD.dat";
    //
            String libpath = "/data/localfacerec/libs";

            //民生激活码：82Y1-1138-V126-UQCD
            //

            //人脸识别引擎库存放路径
            faceEngine = new FaceEngine(libpath);
            //激活引擎
    //        int errorCode = faceEngine.activeOnline(appId, sdkKey, activeKey);
    //        System.out.println("引擎激活errorCode:" + errorCode);

            BufferedReader reader = new BufferedReader(new FileReader(activeKey));
            System.out.println("activeKey文件内容：" + reader.readLine());

            ActiveDeviceInfo activeDeviceInfo = new ActiveDeviceInfo();
            //采集设备信息（可离线）
            int errorCode = faceEngine.getActiveDeviceInfo(activeDeviceInfo);
            System.out.println("采集设备信息errorCode:" + errorCode);
            System.out.println("设备信息:"+activeDeviceInfo.getDeviceInfo());

            System.out.println("激活文件地址：" + activeKey);
            int code = faceEngine.activeOffline(activeKey);
            System.out.println("激活返回值：" + code);


            ActiveFileInfo activeFileInfo = new ActiveFileInfo();
            errorCode = faceEngine.getActiveFileInfo(activeFileInfo);
            System.out.println("获取激活文件errorCode:" + errorCode);
            System.out.println("激活文件信息:" + activeFileInfo.toString());

            /*if (errorCode != 0) {
                System.out.println("激活文件地址：" + activeKey2);
                faceEngine.activeOffline(activeKey2);
                activeFileInfo = new ActiveFileInfo();
                errorCode = faceEngine.getActiveFileInfo(activeFileInfo);
                System.out.println("获取激活文件errorCode:" + errorCode);
                System.out.println("激活文件信息:" + activeFileInfo.toString());

                if (errorCode != 0) {
                    System.out.println("激活文件地址：" + activeKey3);
                    faceEngine.activeOffline(activeKey3);
                    activeFileInfo = new ActiveFileInfo();
                    errorCode = faceEngine.getActiveFileInfo(activeFileInfo);
                    System.out.println("获取激活文件errorCode:" + errorCode);
                    System.out.println("激活文件信息:" + activeFileInfo.toString());
                }
            }*/

            //引擎配置
            EngineConfiguration engineConfiguration = new EngineConfiguration();
            engineConfiguration.setDetectMode(DetectMode.ASF_DETECT_MODE_IMAGE);
            engineConfiguration.setDetectFaceOrientPriority(DetectOrient.ASF_OP_ALL_OUT);
            engineConfiguration.setDetectFaceMaxNum(10);
            engineConfiguration.setDetectFaceScaleVal(16);
            //功能配置
            FunctionConfiguration functionConfiguration = new FunctionConfiguration();
            functionConfiguration.setSupportAge(true);
            functionConfiguration.setSupportFace3dAngle(true);
            functionConfiguration.setSupportFaceDetect(true);
            functionConfiguration.setSupportFaceRecognition(true);
            functionConfiguration.setSupportGender(true);
            functionConfiguration.setSupportLiveness(true);
            functionConfiguration.setSupportIRLiveness(true);
            functionConfiguration.setSupportImageQuality(true);
            engineConfiguration.setFunctionConfiguration(functionConfiguration);

            //初始化引擎
            errorCode = faceEngine.init(engineConfiguration);
            System.out.println("初始化引擎errorCode:" + errorCode);

            String localFilePath = "/data/html/localfacerec/txt";


            File file = new File(localFilePath);
            File[] files = file.listFiles();
            //shop
            if (files != null && files.length > 0) {
                for (File temp : files) {
                    //customer
                    File[] customerFile = temp.listFiles();
                    if (customerFile != null && customerFile.length > 0) {
                        for (File customer : customerFile) {
                            //face
                            File faces[] = customer.listFiles();
                            if (faces != null && faces.length > 0) {
                                for (File face : faces) {
                                    String faceId = face.getName().substring(0, face.getName().indexOf("."));

                                    String personId = customer.getName() + "_" + faceId;
                                    System.out.println(personId);

                                    InputStream input = null;
                                    byte[] byt = null;
                                    try {
                                        input = new FileInputStream(face);

                                        byt = new byte[input.available()];

                                        input.read(byt);
                                    } catch (FileNotFoundException e) {
                                        logger.info("file not find!");
                                    } catch (IOException e) {
                                        logger.info("IOException :" + e);
                                    }finally {
                                        input.close();
                                    }
                                    /*BufferedReader fileReader = new BufferedReader(new FileReader(face));
                                    String content = fileReader.readLine();
                                    fileReader.close();*/
                                    FaceFeature faceFeature = new FaceFeature();
                                    faceFeature.setFeatureData(byt);
                                    customerIdFeatureMap.put(personId, faceFeature);
                                }
                            }
                        }
                    }
                }
            }

        } catch (Exception e) {
            logger.info(e.getMessage());
        }
    }

    public void FaceService2() {
        //从官网获取
        String appId = "gNM8EUAw8KnCB4HTveHSQPzjrGKabrbkEv1Hb5U3FYn";
        String sdkKey = "B7XZB3xGW6uuTEqcF8gFsXjca5KhD7P2GLtdfmLZKu5k";


        faceEngine = new FaceEngine("/data/localfacerec/libs");

        //激活引擎
        int errorCode = faceEngine.activeOnline(appId, sdkKey, "/data/face/82Y11138V13BUTFQ.dat");

        if (errorCode != ErrorInfo.MOK.getValue() && errorCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) {
            System.out.println("引擎激活失败");
        }


        ActiveFileInfo activeFileInfo=new ActiveFileInfo();
        errorCode = faceEngine.getActiveFileInfo(activeFileInfo);
        if (errorCode != ErrorInfo.MOK.getValue() && errorCode != ErrorInfo.MERR_ASF_ALREADY_ACTIVATED.getValue()) {
            System.out.println("获取激活文件信息失败");
        }

        //引擎配置
        EngineConfiguration engineConfiguration = new EngineConfiguration();
        engineConfiguration.setDetectMode(DetectMode.ASF_DETECT_MODE_IMAGE);
        engineConfiguration.setDetectFaceOrientPriority(DetectOrient.ASF_OP_ALL_OUT);
        engineConfiguration.setDetectFaceMaxNum(10);
        engineConfiguration.setDetectFaceScaleVal(16);
        //功能配置
        FunctionConfiguration functionConfiguration = new FunctionConfiguration();
        functionConfiguration.setSupportAge(true);
        functionConfiguration.setSupportFace3dAngle(true);
        functionConfiguration.setSupportFaceDetect(true);
        functionConfiguration.setSupportFaceRecognition(true);
        functionConfiguration.setSupportGender(true);
        functionConfiguration.setSupportLiveness(true);
        functionConfiguration.setSupportIRLiveness(true);
        engineConfiguration.setFunctionConfiguration(functionConfiguration);


        //初始化引擎
        errorCode = faceEngine.init(engineConfiguration);

        if (errorCode != ErrorInfo.MOK.getValue()) {
            System.out.println("初始化引擎失败");
        }
    }

    public String addFace(String faceUrl, Integer customerId, Integer shopId) throws Exception{
        String faceId = System.currentTimeMillis() + "";

        String localFilePath = faceUrl;
        if (faceUrl != null && faceUrl.startsWith("http")) {

            localFilePath = "/data/html/localfacerec/img";
            File file = new File(localFilePath);
            if (!file.exists()) {
                file.mkdir();
            }

            localFilePath += "/" + shopId;
            file = new File(localFilePath);
            if (!file.exists()) {
                file.mkdir();
            }

            localFilePath += "/" + customerId;

            file = new File(localFilePath);
            if (!file.exists()) {
                file.mkdir();
            }

            localFilePath += "/" + faceId + ".png";
            FileDownloader.downloadNet(faceUrl, localFilePath);
        }

        List<FaceInfo> faceInfoList = new ArrayList<FaceInfo>();
        ImageInfo imageInfo = ImageFactory.getRGBData(new File(localFilePath));
        int errorCode = faceEngine.detectFaces(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList);
        System.out.println("人脸检测errorCode:" + errorCode);
        System.out.println("检测到人脸数:" + faceInfoList.size());

        //特征提取
        FaceFeature faceFeature = new FaceFeature();
        errorCode = faceEngine.extractFaceFeature(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList.get(0), faceFeature,2);
        System.out.println("特征提取errorCode:" + errorCode);

        customerIdFeatureMap.put(customerId + "_" + faceId, faceFeature);

        localFilePath = "/data/html/localfacerec/txt";
        File file = new File(localFilePath);
        if (!file.exists()) {
            file.mkdir();
        }

        localFilePath += "/" + shopId;
        file = new File(localFilePath);
        if (!file.exists()) {
            file.mkdir();
        }

        localFilePath += "/" + customerId;

        file = new File(localFilePath);
        if (!file.exists()) {
            file.mkdir();
        }
        localFilePath += "/" + faceId + ".txt";

//        FileWriter fileWriter = new FileWriter(localFilePath);
//        fileWriter.write(new String(faceFeature.getFeatureData()));
//        fileWriter.close();

        File fileWriter = new File(localFilePath);
        FileOutputStream fos = new FileOutputStream(fileWriter);
        fos.write(faceFeature.getFeatureData());
        System.out.println("写入成功");
        fos.close();

        return faceId;
    }

    public void deleteFace(Integer customerId, String faceId, Integer shopId){
        customerIdFeatureMap.remove(customerId + "_" + faceId);
        String txtFilePath = "/data/html/localfacerec/txt/" + shopId + "/" + customerId + "/" + faceId + ".txt";
        File file = new File(txtFilePath);
        if (file.exists()) {
            file.delete();
        }
        String imgFilePath = "/data/html/localfacerec/img/" + shopId + "/" + customerId + "/" + faceId + ".png";
        file = new File(imgFilePath);
        if (file.exists()) {
            file.delete();
        }
    }

    public void deletePerson(Integer customerId, Integer shopId){
        if (customerIdFeatureMap != null && customerIdFeatureMap.size() > 0) {
            List<String> keyList = new ArrayList<>();
            for (Map.Entry<String, FaceFeature> entry : customerIdFeatureMap.entrySet()) {
                if (entry.getKey().startsWith(customerId + "_")) {
                    keyList.add(entry.getKey());
                }
            }
            if (keyList.size() > 0) {
                for (String temp : keyList) {
                    customerIdFeatureMap.remove(temp);
                }
            }
            String txtFilePath = "/data/html/localfacerec/txt/" + shopId + "/" + customerId;
            File file = new File(txtFilePath);
            if (file.exists()) {
                file.delete();
            }
            String imgFilePath = "/data/html/localfacerec/img/" + shopId + "/" + customerId;
            file = new File(imgFilePath);
            if (file.exists()) {
                file.delete();
            }
        }
    }

    public String searchFacesFromMultiple(String faceUrl){
        String faceId = System.currentTimeMillis() + "";

        String localFilePath = faceUrl;
        if (faceUrl != null && faceUrl.startsWith("http")) {

            localFilePath = "/data/html/localfacerec/predict";
            File file = new File(localFilePath);
            if (!file.exists()) {
                file.mkdir();
            }

            localFilePath += "/" + faceId + ".png";
            FileDownloader.downloadNet(faceUrl, localFilePath);
        }

        List<FaceInfo> faceInfoList = new ArrayList<FaceInfo>();
        ImageInfo imageInfo = ImageFactory.getRGBData(new File(localFilePath));
        int errorCode = faceEngine.detectFaces(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList);
        System.out.println("人脸检测errorCode:" + errorCode);
        System.out.println("检测到人脸数:" + faceInfoList.size());

        //特征提取
        FaceFeature faceFeature = new FaceFeature();
        errorCode = faceEngine.extractFaceFeature(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList.get(0), faceFeature,2);
        System.out.println("特征提取errorCode:" + errorCode);

        String resultFaceFeature = null;
        if (customerIdFeatureMap != null && customerIdFeatureMap.size() > 0) {
            FaceSimilar faceSimilar = new FaceSimilar();
            //特征比对
            for (Map.Entry<String, FaceFeature> entry : customerIdFeatureMap.entrySet()) {
                errorCode = faceEngine.compareFaceFeature(faceFeature, entry.getValue(), faceSimilar);

                System.out.println("相似度：" + faceSimilar.getScore());
                if (faceSimilar.getScore() > 0.88) {
//                    return entry.getKey();
                    resultFaceFeature = entry.getKey();
                }
            }
        }
        return resultFaceFeature;
    }

    public boolean detectFace(String faceUrl){
        //人脸属性检测
        String faceId = System.currentTimeMillis() + "";

        String localFilePath = faceUrl;
        if (faceUrl != null && faceUrl.startsWith("http")) {

            localFilePath = "/data/html/localfacerec/predict";
            File file = new File(localFilePath);
            if (!file.exists()) {
                file.mkdir();
            }

            localFilePath += "/" + faceId + ".png";
            FileDownloader.downloadNet(faceUrl, localFilePath);
        }

        //人脸检测
        List<FaceInfo> faceInfoList = new ArrayList<FaceInfo>();
        ImageInfo imageInfo = ImageFactory.getRGBData(new File(localFilePath));

        System.out.println(imageInfo);
        System.out.println(imageInfo.getWidth());

        int errorCode = faceEngine.detectFaces(imageInfo.getImageData(), imageInfo.getWidth(), imageInfo.getHeight(), imageInfo.getImageFormat(), faceInfoList);
        System.out.println("人脸检测errorCode:" + errorCode);
        System.out.println("检测到人脸数:" + faceInfoList.size());

        if (faceInfoList.size() > 0) {
            System.out.println(faceInfoList.get(0));
            System.out.println(faceInfoList.get(0).getFaceId());
            if(faceInfoList.get(0).getOrient()> 0){
                return true;
            }
        }
        return false;
    }

}
